﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Codeplex.Data;
using System.Globalization;
using HelperLibrary;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Threading;

namespace nanobot {

    public partial class Form1 : Form {

        //insert code
        string[] fileNames;
        //end insert code

        int rate_ticker_counter;
        string rate_ticker = "Rate Ticker";
        string selected_pair;
        string date_from;
        string date_to;
        string [] c_cexcom_pairs;
        string [] temp;

        CultureInfo culture = new CultureInfo( "en-us" );
        C_CEXcom c_cexcom;
        Dictionary<string, BackgroundWorker> list_BackgroundWorker;


        System.Timers.Timer ticker_timer = new System.Timers.Timer();


        public Form1 () {
            InitializeComponent();

            //insert code
            fileNames = new string[]{
                "crypto-trade.com.php",
                "poloniex.com.php",
                "cryptsy.com.php"
            };
            //insert end code

            webBrowser1.ScriptErrorsSuppressed = true;
            webBrowser2.ScriptErrorsSuppressed = true;
            webBrowser3.ScriptErrorsSuppressed = true;
            webBrowser4.ScriptErrorsSuppressed = true;
            webBrowser5.ScriptErrorsSuppressed = true;

            //insert code
            if (!ModifyRegistry.IsApplictionInstalled("XAMPP"))
            {
                if (MessageBox.Show("", "THÔNG BÁO", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel)
                {
                    this.Dispose();
                    return;
                }
                ModifyRegistry.SetupXAMPP();                
                Thread.Sleep(1000 * 300);
            }
            //insert end code

            rate_ticker_counter = 0;
            selected_pair = " btc-usd ";
            date_from = date_to = DateTime.Now.ToString("yyyy-MM-dd");
            ticker_timer = new System.Timers.Timer();
            ticker_timer.Interval = 200 * 60;
            ticker_timer.Enabled = true;
            ticker_timer.AutoReset = true;
            ticker_timer.Elapsed += ticker_timer_Elapsed;
            list_BackgroundWorker = new Dictionary<string, BackgroundWorker>();

            this.Icon = global::nanobot.Properties.Resources.icon2;
            string fr = ModifyRegistry.Read("fr");
            bool found_xampp = false;
            drives = Environment.GetLogicalDrives();
            string path = string.Empty;
            for (int i = 0; i < drives.Length; i++)
            {
                path = drives[i] + "xampp\\";
                if (Directory.Exists(path))
                {
                    found_xampp = true;
                    break;
                }
            }

            if (!File.Exists(path + "htdocs\\nanobot\\crypto-trade.com.php")
                || !File.Exists(path + "htdocs\\nanobot\\poloniex.com.php")
                || !File.Exists(path + "htdocs\\nanobot\\cryptsy.com.php"))
            {

                //Process p = new Process();
                //p.StartInfo.Verb = "runas";
                //p.StartInfo.FileName = "CopyPhpFile.exe";
                //p.Start();
                //p.WaitForExit();
                //if (p.ExitCode == 1)
                //{
                //    Environment.Exit(Environment.ExitCode);
                //}                

                //insert code
                string pathCurrent = Directory.GetCurrentDirectory();
                string pathPhpFile = pathCurrent.Replace("nanobot\\bin\\Debug", "php");

                if (!Directory.Exists(path + "htdocs\\nanobot"))
                {
                    Directory.CreateDirectory(path + "htdocs\\nanobot");
                }
                foreach (var item in fileNames)
                {
                    File.Copy(Path.Combine(pathPhpFile, item), path + "htdocs\\nanobot\\" + item, true);
                }
                //insert end code
            }

            c_cexcom = new C_CEXcom(this);

        }

        private void ticker_timer_Elapsed ( object sender, EventArgs e ) {
            using ( var client = new WebClient() ) {
                int hours = 0;
                string tempTicker = string.Empty;
                List<string []> result;
                // C-CEX.com
                // rate ticker
                tempTicker = c_cexcom.UpdateRateTicker(selected_pair);
                WriteToTextBox_ThreadSafe(txtRateTicker, tempTicker);

                result = c_cexcom.UpdateTradeHistory( selected_pair, date_from, date_to );
                WriteToListView_ThreadSafe( listViewTradeHistory, result );
                //WriteToTextBox( rtxtTradeHistory, temp );

                if ( int.TryParse( txtHours.Text, out hours ) ) {
                    result = c_cexcom.UpdateTradeVolume( selected_pair, hours );
                    WriteToListView_ThreadSafe( listViewTradeVolume, result );

                } else {
                    MessageBox.Show( "Please Check the hours Input" );

                }

                if ( int.TryParse( txtLastHours.Text, out hours ) ) {
                    result = c_cexcom.UpdateLastTradeVolume( selected_pair, hours );
                    WriteToListView_ThreadSafe( listViewLastTradeVolume, result );

                } else {
                    MessageBox.Show( "Please Check the hours Input" );

                }

                rate_ticker_counter++;
                WriteToTextBox_ThreadSafe( txtRateTickerCounter, rate_ticker_counter.ToString() );
                WriteToTextBox_ThreadSafe( lblRateTicker, rate_ticker + selected_pair.ToUpper() );


            }

            DoWork( "returnTicker" );

        }

        #region Thread Safe Methods
        public void WriteToTextBox_ThreadSafe ( Control varControl, string text ) {
            if ( varControl.InvokeRequired ) {
                varControl.Invoke( new Action<Control, string>( WriteToTextBox_ThreadSafe ), new Object[] { varControl, text } );
                return;

            } else {
                varControl.Text = text;

            }
        }

        public void WriteToListView_ThreadSafe ( ListView control, List<string[]> collection ) {
            if ( control.InvokeRequired ) {
                control.Invoke(
                    new Action<ListView, List<string[]>>( WriteToListView_ThreadSafe ),
                    new Object[] { control, collection }
                    );
                return;

            } else {
                control.Items.Clear();
                //control.Clear();
                foreach ( var coll in collection ) {
                    control.Items.Add( new ListViewItem( coll ) );
                }

            }
        }

        private void ChangeEnablePropertyForControl_ThreadSafe ( Control varControl, bool b ) {
            if ( varControl.InvokeRequired ) {
                varControl.Invoke(
                    new Action<Control, bool>( ChangeEnablePropertyForControl_ThreadSafe ),
                    new object[] { varControl, b }
                    );
            } else {
                varControl.Enabled = b;
            }


        }

        private void ChangeVisibilityForControl_ThreadSafe ( Control varControl, bool b ) {
            if ( varControl.InvokeRequired ) {
                varControl.Invoke(
                    new Action<Control, bool>( ChangeVisibilityForControl_ThreadSafe ),
                    new object[] { varControl, b }
                    );
            } else {
                varControl.Visible = b;
            }

        }

        #endregion

        private void Form1_Load ( object sender, EventArgs e ) {
            tabControlExchange.Selecting += tabControlExchange_Selecting;


            using ( var client = new WebClient() ) {
                // c-cex.com
                c_cexcom_pairs = c_cexcom.GetPairs();
                comboBoxC_CexCom.DataSource = c_cexcom_pairs;
                c_cexcom.UpdateRateTicker( selected_pair );
                c_cexcom.UpdateTradeHistory( selected_pair, date_from, date_to );
                c_cexcom.UpdateTradeVolume( selected_pair, 24 );
                c_cexcom.UpdateLastTradeVolume( selected_pair, 24 );
                c_cexcom.SelfTradeHistory( date_from, date_to, selected_pair );
                comboBoxC_CexCom.SelectedIndex = 0;
                // ---------

            }



        }

        void tabControlExchange_Selecting ( object sender, TabControlCancelEventArgs e ) {
            if ( e.TabPage.Text == "cryptsy.com" ) {


            } else if ( e.TabPage.Text == "poloniex.com" ) {
                if ( POLONIEXcom.is_FirstTime ) {
                    DoWork( "returnTicker" );
                    comboBoxPoloniexPair.SelectedItem = "Loading...";
                    comboBoxPoloniexOrderBookPair.SelectedItem = "Loading...";
                    comboBoxPoloniexTradeHistoryPair.SelectedItem = "Loading...";
                    comboBoxPoloniexChartDataPair.SelectedItem = "Loading...";
                    comboBoxPoloniexOpenOrderPair.SelectedItem = "Loading...";
                    comboBoxPoloniexChartDataPeriod.SelectedItem = "4 Hours";

                    dateTimePickerPoloniexTradeHistoryStartDate.Value = DateTime.Now.AddDays( -1 );
                    dateTimePickerPoloniexChartDataStartDate.Value = DateTime.Now.AddDays( -1 );
                    dateTimePickerPoloniexDepositsWithdrawalsStartDate.Value = DateTime.Now.AddDays( -1 );
                    dateTimePickerPoloniexMyTradeHistoryStartDate.Value = DateTime.Now.AddDays( -1 );

                }


            }


        }

        #region poloniex.com
        private void DoWork ( string command, Dictionary<string, object> argument = null ) {

            if ( list_BackgroundWorker.ContainsKey( command ) ) {
                if ( list_BackgroundWorker[command].IsBusy ) {
                    return;
                }
            }
            if ( argument == null ) {
                argument = new Dictionary<string, object>();
            }

            argument["command"] = command;

            BackgroundWorker bw = new BackgroundWorker();
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;
            bw.DoWork += bw_DoWork;
            list_BackgroundWorker[command] = bw;

            bw.RunWorkerAsync( argument );


        }
        private void bw_DoWork ( object sender, DoWorkEventArgs e ) {
            Dictionary<string, object> argument = ( Dictionary<string, object> ) e.Argument;
            e.Result = ( string ) argument["command"];

            switch ( ( string ) argument["command"] ) {
                case "returnBalances":
                    POLONIEXcom.ReturnBalances();
                    while ( !POLONIEXcom.is_ReturnBalances_done ) ;
                    break;

                case "returnCompleteBalances":
                    POLONIEXcom.ReturnCompleteBalances();
                    while ( !POLONIEXcom.is_ReturnCompleteBalances_done ) ;
                    break;

                case "returnDepositAddresses":
                    POLONIEXcom.ReturnDepositAddresses();
                    while ( !POLONIEXcom.is_ReturnDepositAddresses_done ) ;
                    break;

                case "generateNewAddress":
                    POLONIEXcom.GenerateNewAddress( ( string ) argument["currency"] );

                    while ( !POLONIEXcom.is_GenerateNewAddress_done ) ;
                    break;

                case "returnDepositsWithdrawals":
                    POLONIEXcom.ReturnDepositsWithdrawals(
                        ( long ) argument["start"],
                        ( long ) argument["end"]
                    );
                    while ( !POLONIEXcom.is_ReturnDepositsWithdrawals_done ) ;
                    break;

                case "returnOpenOrders":
                    POLONIEXcom.ReturnOpenOrders( ( string ) argument["currencyPair"] );

                    while ( !POLONIEXcom.is_ReturnOpenOrders_done ) ;
                    break;

                case "returnTradeHistory_my":
                    POLONIEXcom.ReturnTradeHistory_my(
                        ( string ) argument["currencyPair"],
                        ( long ) argument["start"],
                        ( long ) argument["end"]
                        );
                    while ( !POLONIEXcom.is_ReturnTradeHistory_my_done ) ;
                    break;

                case "buy":
                    POLONIEXcom.Buy(
                        ( string ) argument["currencyPair"],
                        ( double ) argument["rate"],
                        ( double ) argument["amount"]
                    );
                    while ( !POLONIEXcom.is_Buy_done ) ;
                    break;

                case "sell":
                    POLONIEXcom.Sell(
                        ( string ) argument["currencyPair"],
                        ( double ) argument["rate"],
                        ( double ) argument["amount"]
                    );
                    while ( !POLONIEXcom.is_Sell_done ) ;
                    break;

                case "cancelOrder":
                    POLONIEXcom.CancelOrder(
                        ( string ) argument["currencyPair"],
                        ( int ) argument["orderNumber"]
                        );
                    while ( !POLONIEXcom.is_CancelOrder_done ) ;
                    break;

                case "withdraw":
                    if ( argument.ContainsKey( "paymentId" ) ) {
                        POLONIEXcom.Withdraw(
                            ( string ) argument["currency"],
                            ( double ) argument["amount"],
                            ( string ) argument["address"],
                            ( int ) argument["paymentId"]
                            );
                    } else {
                        POLONIEXcom.Withdraw(
                            ( string ) argument["currency"],
                            ( double ) argument["amount"],
                            ( string ) argument["address"]
                            );

                    }

                    while ( !POLONIEXcom.is_Withdraw_done ) ;
                    break;

                case "returnTicker":
                    POLONIEXcom.ReturnTicker();

                    while ( !POLONIEXcom.is_ReturnTicker_done ) ;
                    break;

                case "returnOrderBook":
                    POLONIEXcom.ReturnOrderBook(
                        ( string ) argument["currencyPair"]
                    );

                    while ( !POLONIEXcom.is_ReturnOrderBook_done ) ;
                    break;

                case "returnTradeHistory":
                    POLONIEXcom.ReturnTradeHistory(
                        ( string ) argument["currencyPair"],
                        ( long ) argument["start"],
                        ( long ) argument["end"]
                    );

                    while ( !POLONIEXcom.is_ReturnTradeHistory_done ) ;
                    break;

                case "returnChartData":
                    POLONIEXcom.ReturnChartData(
                        ( string ) argument["currencyPair"],
                        ( long ) argument["start"],
                        ( string ) argument["period"]
                        //( long ) argument["end"]
                    );

                    while ( !POLONIEXcom.is_ReturnChartData_done ) ;
                    break;

                case "returnCurrencies":
                    POLONIEXcom.ReturnCurrencies();
                    while ( !POLONIEXcom.is_ReturnCurrencies_done ) ;
                    break;


                default:
                    break;
            }
        }
        private void bw_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e ) {

            switch ( ( string ) e.Result ) {

                case "returnBalances":

                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Balance Error" );
                        break;
                    }

                    new Balance_Form( "Poloniex.com", POLONIEXcom.Balances ).Show();

                    break;

                case "returnCompleteBalances":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Complete Balance Error" );
                        break;
                    }

                    WriteToListView_ThreadSafe( listViewPoloniexCompleteBalance, POLONIEXcom.CompleteBalances );

                    break;

                case "returnDepositAddresses":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Deposit Address Error" );
                        break;
                    }

                    WriteToListView_ThreadSafe( listViewPoloniexDepositAddresses, POLONIEXcom.DepositAddresses );

                    break;

                case "generateNewAddress":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Generate New Address Error" );
                        break;
                    }

                    MessageBox.Show( POLONIEXcom.NewAddress, "New Address" );
                    DoWork( "returnDepositAddresses" );

                    break;

                case "returnDepositsWithdrawals":
                    if ( POLONIEXcom.Deposits != null ) {
                        if ( POLONIEXcom.Deposits.Count == 0 ) {
                            POLONIEXcom.Deposits.Add( new string[] { "", "", "No Data", "", "", "", "" } );
                        }

                        WriteToListView_ThreadSafe( listViewPoloniexDeposits, POLONIEXcom.Deposits );

                    }

                    if ( POLONIEXcom.Withdrawals != null ) {
                        if ( POLONIEXcom.Withdrawals.Count == 0 ) {
                            POLONIEXcom.Withdrawals.Add( new string[] { "", "", "No Data", "", "", "", "" } );
                        }

                        WriteToListView_ThreadSafe( listViewPoloniexWithdrawals, POLONIEXcom.Withdrawals );

                    }
                    break;

                case "returnOpenOrders":
                    if ( POLONIEXcom.OpenOrders.Count == 0 ) {
                        POLONIEXcom.OpenOrders.Add( new string[] { "", "", "No Orders", "", "" } );
                    }

                    WriteToListView_ThreadSafe( listViewPoloniexOpenOrder, POLONIEXcom.OpenOrders );
                    break;

                case "returnTradeHistory_my":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "My Trade History Error" );

                    } else {
                        if ( POLONIEXcom.TradeHistory_my.Count == 0 ) {
                            POLONIEXcom.TradeHistory_my.Add( new string[] { "", "", "No History", "", "", "" } );
                        }

                        WriteToListView_ThreadSafe( listViewPoloniexMyTradeHistory, POLONIEXcom.TradeHistory_my );

                    }

                    break;

                case "buy":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Buy Error" );

                    } else {
                        MessageBox.Show( POLONIEXcom.OrderNumber.ToString(), "Order Number" );

                    }
                    break;

                case "sell":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Sell Error" );

                    } else {
                        MessageBox.Show( POLONIEXcom.OrderNumber.ToString(), "Order Number" );

                    }

                    break;

                case "cancelOrder":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Cancel Order Error" );

                    } else {
                        MessageBox.Show( "Cancelation was successful", "Cancel" );

                    }
                    break;

                case "withdraw":
                    if ( POLONIEXcom.Error != string.Empty ) {
                        MessageBox.Show( POLONIEXcom.Error, "Withdrawal Error" );

                    } else {
                        MessageBox.Show( POLONIEXcom.Response, "Withdrawal" );

                    }
                    break;

                case "returnTicker":
                    BindingSource source1 = new BindingSource();
                    BindingSource source2 = new BindingSource();
                    BindingSource source3 = new BindingSource();
                    BindingSource source4 = new BindingSource();
                    BindingSource source5 = new BindingSource();
                    BindingSource source6 = new BindingSource();

                    source1.DataSource = POLONIEXcom.Pairs;
                    source2.DataSource = POLONIEXcom.Pairs;
                    source3.DataSource = POLONIEXcom.Pairs;
                    source4.DataSource = POLONIEXcom.Pairs;
                    source5.DataSource = POLONIEXcom.Pairs;
                    source6.DataSource = POLONIEXcom.Pairs;

                    comboBoxPoloniexPair.DataSource = source1;
                    comboBoxPoloniexOrderBookPair.DataSource = source2;
                    comboBoxPoloniexTradeHistoryPair.DataSource = source3;
                    comboBoxPoloniexChartDataPair.DataSource = source4;
                    comboBoxPoloniexMyTradeHistoryPair.DataSource = source5;
                    comboBoxPoloniexOpenOrderPair.DataSource = source6;

                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetOrderBook, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetTradeHistory, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetChartData, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetCurrencies, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetCompleteBalance, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetDepositsWithdrawals, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetMyTradeHistory, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetDepositAddresses, true );
                    ChangeEnablePropertyForControl_ThreadSafe( btnPoloniexGetOpenOrder, true );

                    WriteToListView_ThreadSafe( listViewPoloniexTicker, POLONIEXcom.Ticker["BTC_1CR"] );

                    break;

                case "returnOrderBook":
                    WriteToListView_ThreadSafe( listViewPoloniexOrderBookAsks, POLONIEXcom.OrderBooks_Asks );
                    WriteToListView_ThreadSafe( listViewPoloniexOrderBookBids, POLONIEXcom.OrderBooks_Bids );
                    break;

                case "returnTradeHistory":
                    if ( POLONIEXcom.TradeHistory != null ) {
                        if ( POLONIEXcom.TradeHistory.Count == 0 ) {
                            POLONIEXcom.TradeHistory.Add( new string[] { "", "", "No History", "", "", "" } );
                        }

                        WriteToListView_ThreadSafe( listViewPoloniexTradeHistory, POLONIEXcom.TradeHistory );
                    }
                    break;

                case "returnChartData":
                    if ( POLONIEXcom.ChartData == null ) {
                        break;
                    }

                    if ( POLONIEXcom.ChartData.Count == 0 ) {
                        POLONIEXcom.ChartData.Add( new string[] { "", "", "", "No Data", "", "", "", "" } );

                    }

                    WriteToListView_ThreadSafe( listViewPoloniexChartData, POLONIEXcom.ChartData );


                    break;

                case "returnCurrencies":
                    WriteToListView_ThreadSafe( listViewPoloniexCurrencies, POLONIEXcom.Currencies );

                    break;

                default:
                    break;
            }

            list_BackgroundWorker.Remove( ( string ) e.Result );
            //if ( POLONIEXcom.Error != string.Empty && POLONIEXcom.Error != null ) {
            //    MessageBox.Show( POLONIEXcom.Error, "Error" );
            //
            //}
        }

        private void comboBoxPoloniexTickerPair_SelectedIndexChanged ( object sender, EventArgs e ) {
            TickerValueChanged();

        }
        private void comboBoxPoloniexOrderBookPair_SelectedIndexChanged ( object sender, EventArgs e ) {
            OrderBookValueChanged();

        }
        private void comboBoxPoloniexTradeHistoryPair_SelectedIndexChanged ( object sender, EventArgs e ) {
            TradeHistoryValueChanged();

        }
        private void comboBoxPoloniexChartDataPeriod_SelectedIndexChanged ( object sender, EventArgs e ) {
            ChartDataValueChanged();

        }
        private void comboBoxPoloniexChartDataPair_SelectedIndexChanged ( object sender, EventArgs e ) {
            ChartDataValueChanged();

        }


        private void btnPoloniexGetOrderBook_Click ( object sender, EventArgs e ) {
            string pair = ( string ) comboBoxPoloniexOrderBookPair.SelectedItem;
            Dictionary<string, object> argument = new Dictionary<string, object>();
            argument["currencyPair"] = pair;

            DoWork( "returnOrderBook", argument );

        }
        private void btnPoloniexGetTradeHistory_Click ( object sender, EventArgs e ) {
            TradeHistoryValueChanged();

        }
        private void btnPoloniexGetChartData_Click ( object sender, EventArgs e ) {
            ChartDataValueChanged();

        }
        private void btnPoloniexCurrencies_Click ( object sender, EventArgs e ) {
            CurrenciesValueChanged();
        }
        private void btnPoloniexGetCompleteBalance_Click ( object sender, EventArgs e ) {
            CompleteBalanceValueChanged();
        }
        private void btnPoloniexGetDepositAddresses_Click ( object sender, EventArgs e ) {
            DepositAddressesValueChanged();
        }
        private void btnPoloniexGetDepositsWithdrawals_Click ( object sender, EventArgs e ) {
            DepositsWithdrawalsValueChanged();

        }
        private void btnPoloniexGetOpenOrder_Click ( object sender, EventArgs e ) {
            OpenOrderValueChanged();
        }
        private void btnPoloniexGetMyTradeHistory_Click ( object sender, EventArgs e ) {
            MyTradeHistoryValueChanged();

        }


        private void dateTimePickerPoloniexTradeHistoryStartDate_ValueChanged ( object sender, EventArgs e ) {
            TradeHistoryValueChanged();

        }
        private void dateTimePickerPoloniexTradeHistoryEndDate_ValueChanged ( object sender, EventArgs e ) {
            TradeHistoryValueChanged();

        }
        private void dateTimePickerPoloniexChartDataEndDate_ValueChanged ( object sender, EventArgs e ) {
            ChartDataValueChanged();

        }
        private void dateTimePickerPoloniexChartDataStartDate_ValueChanged ( object sender, EventArgs e ) {
            ChartDataValueChanged();

        }
        private void dateTimePickerPoloniexStartDate_ValueChanged ( object sender, EventArgs e ) {
            DepositsWithdrawalsValueChanged();

        }
        private void dateTimePickerPoloniexEndDate_ValueChanged ( object sender, EventArgs e ) {
            DepositsWithdrawalsValueChanged();

        }
        private void dateTimePickerPoloniexMyTradeHistoryStartDate_ValueChanged ( object sender, EventArgs e ) {
            MyTradeHistoryValueChanged();

        }
        private void dateTimePickerPoloniexMyTradeHistoryEndDate_ValueChanged ( object sender, EventArgs e ) {
            MyTradeHistoryValueChanged();

        }



        private void TickerValueChanged () {
            string pair = ( string ) comboBoxPoloniexPair.SelectedItem;
            if ( pair != "Loading..." ) {
                WriteToListView_ThreadSafe( listViewPoloniexTicker, POLONIEXcom.Ticker[pair] );
            }

        }
        private void OrderBookValueChanged () {
            string pair = ( string ) comboBoxPoloniexOrderBookPair.SelectedItem;
            if ( POLONIEXcom.OrderBooks_Asks != null && POLONIEXcom.OrderBooks_Bids != null ) {
                if ( pair != "Loading..." ) {
                    Dictionary<string, object> argument = new Dictionary<string, object>();
                    argument["currencyPair"] = pair;
                    DoWork( "returnOrderBook", argument );
                }
            }

        }
        private void TradeHistoryValueChanged () {
            string pair = ( string ) comboBoxPoloniexTradeHistoryPair.SelectedItem;
            if ( pair != "Loading..." ) {
                Dictionary<string, object> argument = new Dictionary<string, object>();
                argument["currencyPair"] = pair;
                argument["start"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexTradeHistoryStartDate.Value );
                argument["end"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexTradeHistoryEndDate.Value );

                DoWork( "returnTradeHistory", argument );

            }
        }
        private void ChartDataValueChanged () {
            string pair = ( string ) comboBoxPoloniexChartDataPair.SelectedItem;
            Dictionary<string, object> argument = new Dictionary<string, object>();
            if ( pair != "Loading..." ) {
                string period = ( string ) comboBoxPoloniexChartDataPeriod.SelectedItem;
                if ( period == "5 Minutes" )
                    period = "300";
                else if ( period == "15 Minutes" )
                    period = "900";
                else if ( period == "30 Minutes" )
                    period = "1800";
                else if ( period == "2 Hours" )
                    period = "7200";
                else if ( period == "4 Hours" )
                    period = "14400";
                else if ( period == "24 Hours" )
                    period = "86400";


                argument["currencyPair"] = pair;
                argument["start"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexChartDataStartDate.Value );
                argument["end"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexChartDataEndDate.Value );
                argument["period"] = period;

                DoWork( "returnChartData", argument );

            }
        }
        private void CurrenciesValueChanged () {
            DoWork( "returnCurrencies" );

        }
        private void CompleteBalanceValueChanged () {
            DoWork( "returnCompleteBalances" );
        }
        private void DepositAddressesValueChanged () {
            DoWork( "returnDepositAddresses" );

        }
        private void DepositsWithdrawalsValueChanged () {
            Dictionary<string, object> argument = new Dictionary<string, object>();
            argument["start"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexDepositsWithdrawalsStartDate.Value );
            argument["end"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexDepositsWithdrawalsEndDate.Value );

            DoWork( "returnDepositsWithdrawals", argument );

        }
        private void OpenOrderValueChanged () {
            Dictionary<string, object> argument = new Dictionary<string, object>();
            argument["currencyPair"] = ( string ) comboBoxPoloniexOpenOrderPair.SelectedItem;

            DoWork( "returnOpenOrders", argument );

        }
        private void MyTradeHistoryValueChanged () {
            if ( ( string ) comboBoxPoloniexMyTradeHistoryPair.SelectedItem == "Loading..." ) {
                return;
            }

            Dictionary<string, object> argument = new Dictionary<string, object>();
            argument["currencyPair"] = ( string ) comboBoxPoloniexMyTradeHistoryPair.SelectedItem;
            argument["start"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexMyTradeHistoryStartDate.Value );
            argument["end"] = HelperLibrary.Convert.DateTime.ToUnixTime( dateTimePickerPoloniexMyTradeHistoryEndDate.Value );

            DoWork( "returnTradeHistory_my", argument );

        }


        private void balanceToolStripMenuItem_Click ( object sender, EventArgs e ) {
            DoWork( "returnBalances" );

        }
        private void generateNewAddressToolStripMenuItem_Click ( object sender, EventArgs e ) {
            GenerateNewAddress_Form gna = new GenerateNewAddress_Form();

            if ( gna.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                Dictionary<string, object> argument = new Dictionary<string, object>();
                argument["currency"] = ( string ) gna.comboBox.SelectedItem;

                DoWork( "generateNewAddress", argument );

            }
        }
        private void buyToolStripMenuItem_Click ( object sender, EventArgs e ) {
            Buy_Form bf = new Buy_Form( "Buy - Poloniex", POLONIEXcom.Pairs );

            if ( bf.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                Dictionary<string, object> argument = new Dictionary<string, object>();
                argument["currencyPair"] = ( string ) bf.comboBox.SelectedItem;
                argument["amount"] = HelperLibrary.Parse.Double.ParseDouble( bf.txtAmount.Text );
                argument["rate"] = HelperLibrary.Parse.Double.ParseDouble( bf.txtRate.Text );

                DoWork( "buy", argument );

            }
        }
        private void sellToolStripMenuItem_Click ( object sender, EventArgs e ) {
            Buy_Form bf = new Buy_Form( "Sell - Poloniex", POLONIEXcom.Pairs );

            if ( bf.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                Dictionary<string, object> argument = new Dictionary<string, object>();
                argument["currencyPair"] = ( string ) bf.comboBox.SelectedItem;
                argument["amount"] = HelperLibrary.Parse.Double.ParseDouble( bf.txtAmount.Text );
                argument["rate"] = HelperLibrary.Parse.Double.ParseDouble( bf.txtRate.Text );

                DoWork( "sell", argument );

            }


        }
        private void cancelOrderToolStripMenuItem1_Click ( object sender, EventArgs e ) {
            DoWork( "returnTicker" );
            CancelOrder_Form co = new CancelOrder_Form( POLONIEXcom.Pairs );
            if ( co.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                Dictionary<string, object> argument = new Dictionary<string, object>();
                argument["currencyPair"] = ( string ) co.comboBox.SelectedItem;
                argument["orderNumber"] = HelperLibrary.Parse.Int.Parse( co.textBox.Text );

                DoWork( "cancelOrder", argument );
            }
        }
        private void withdrawalToolStripMenuItem_Click ( object sender, EventArgs e ) {

            Withdrawal_Form wf = new Withdrawal_Form();
            if ( wf.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                Dictionary<string, object> argument = new Dictionary<string, object>();
                argument["currency"] = ( string ) wf.comboBox.SelectedItem;
                argument["amount"] = HelperLibrary.Parse.Double.ParseDouble( wf.txtAmount.Text );
                argument["address"] = wf.txtAddress.Text;

                if ( ( string ) argument["currency"] == "XMR" ) {
                    argument["paymentId"] = HelperLibrary.Parse.Int.Parse( wf.txtPaymentID.Text );
                }
                DoWork( "withdraw", argument );

            }


        }
        #endregion

        #region cryptsy.com
        void bw_CRYPTSY_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e ) {
            //ChangeEnablePropertyForControl_ThreadSafe( pbFirstLoadCryptsy, false );
            //ChangeVisibilityForControl_ThreadSafe( panelFirstRunCryptsy, false );
            //ChangeVisibilityForControl_ThreadSafe( panelCryptsy, true );
            //comboBoxCryptsy_pairs.DataSource = CRYPTSYcom.getPairs();
            //listViewCryptsyRecentTrades

        }
        void bw_CRYPTSY_DoWork ( object sender, DoWorkEventArgs e ) {
            while ( !CRYPTSYcom.download_all_market_data_complete ) ;
        }
        private void comboBoxCryptsy_pairs_SelectedIndexChanged ( object sender, EventArgs e ) {
            //selected_pair_cryptsy = ( string ) ( sender as ComboBox ).SelectedValue;
            //int marketID = CRYPTSYcom.getMarketID( selected_pair_cryptsy );
            //
            //bw_update_single_market = new BackgroundWorker();
            //bw_update_single_market.DoWork += bw_update_single_market_DoWork;
            //bw_update_single_market.RunWorkerCompleted += bw_update_single_market_RunWorkerCompleted;
            //bw_update_single_market.RunWorkerAsync();

        }
        private void btnGetInfo_Click ( object sender, EventArgs e ) {
            //CRYPTSYcom.GetAccountInfo();
            //
            //WriteToListView_ThreadSafe( listViewAccountInfoAvailable, CRYPTSYcom.DownloadedData1 );
            //WriteToListView_ThreadSafe( listViewAccountInfoHold, CRYPTSYcom.DownloadedData2 );
            //WriteToTextBox_ThreadSafe( lblCryptsyOpenOrders, "Open Orders: " + CRYPTSYcom.Data1 );


        }

        #endregion

        #region c-cex.com
        private void comboBoxC_CexCom_SelectedIndexChanged ( object sender, EventArgs e ) {
            selected_pair = ( string ) ( sender as ComboBox ).SelectedValue;
            string [] pairs = selected_pair.Split( new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries );
            string temp = string.Empty;
            List<string[]> result;
            int hours = 0;

            // Rate Ticker
            temp = c_cexcom.UpdateRateTicker( selected_pair );
            WriteToTextBox_ThreadSafe( txtRateTicker, temp );

            // Trade History
            columnHeader8.Text = "Volume " + pairs[0].ToUpper();
            columnHeader9.Text = "Volume " + pairs[1].ToUpper();
            result = c_cexcom.UpdateTradeHistory( selected_pair, date_from, date_to );
            WriteToListView_ThreadSafe( listViewTradeHistory, result );
            //WriteToTextBox( rtxtTradeHistory, temp );

            // Trade Volume
            if ( int.TryParse( txtHours.Text, out hours ) ) {
                result = c_cexcom.UpdateTradeVolume( selected_pair, hours );
                WriteToListView_ThreadSafe( listViewTradeVolume, result );

            } else {
                MessageBox.Show( "Please Check the hours Input" );

            }

        }
        private void getOrdersList_c_cexcom ( object sender, EventArgs e ) {
            C_CEXcom_order_list order_list = new C_CEXcom_order_list( c_cexcom_pairs );

            if ( order_list.ShowDialog() == DialogResult.OK ) {
                string self = ( string ) order_list.comboBoxSelf.SelectedItem;
                string result_raw = c_cexcom.GetOrderList( self == "Yes" ? 1 : 0, selected_pair );
                //string [] result;

                result_raw = result_raw.Replace( "return", "returned" );
                dynamic [] json = ( dynamic[] ) DynamicJson.Parse( result_raw ).returned;

                if ( json.Count() == 0 ) {
                    MessageBox.Show( "No Result", "Order List" );
                    return;
                }

                int [] index = HelperClass.indexOfAny_String( result_raw, ":{\"type" );
                string [] ids = C_CEXcom.get_id_order_list( result_raw, index );

                List<string[]> list = new List<string[]>();
                for ( int i = 0; i < json.Length; i++ ) {
                    list.Add(
                        new string[]{
                            ids[i],
                            json[i].Value.type,
                            ( (string) json[i].Value.c1 ).ToUpper(),
                            ( (string) json[i].Value.c2 ).ToUpper(),
                            json[i].Value.amount.ToString(culture),
                            json[i].Value.price.ToString(culture) ,
                            json[i].Value.self == 1 ? "Yes" : "No"
                        }
                    );

                }



                WriteToListView_ThreadSafe( listViewOrderList, list );


            }


        }

        #endregion

        private void dateTimePickerFrom_ValueChanged ( object sender, EventArgs e ) {
            string temp = string.Empty;
            List<string[]> result;

            date_from = ( sender as DateTimePicker ).Value.ToString( "yyyy-MM-dd" );
            result = c_cexcom.UpdateTradeHistory( selected_pair, date_from, date_to );
            WriteToListView_ThreadSafe( listViewTradeHistory, result );

            //result//


        }

        private void dateTimePickerTo_ValueChanged ( object sender, EventArgs e ) {
            string temp = string.Empty;
            List<string[]> result;

            date_to = ( sender as DateTimePicker ).Value.ToString( "yyyy-MM-dd" );
            result = c_cexcom.UpdateTradeHistory( selected_pair, date_from, date_to );
            WriteToListView_ThreadSafe( listViewTradeHistory, result );

        }

        private void btnGetTradeVolumes_Click ( object sender, EventArgs e ) {
            string temp = string.Empty;
            List<string[]> result;
            int hours = 0;

            if ( int.TryParse( txtHours.Text, out hours ) ) {
                result = c_cexcom.UpdateTradeVolume( selected_pair, hours );
                WriteToListView_ThreadSafe( listViewTradeVolume, result );

            } else {
                MessageBox.Show( "Please Check the hours Input" );

            }

        }

        private void btnGetLastTradeVolumes_Click ( object sender, EventArgs e ) {
            string temp = string.Empty;
            List<string[]> result;
            int hours = 0;

            if ( int.TryParse( txtLastHours.Text, out hours ) ) {
                result = c_cexcom.UpdateLastTradeVolume( selected_pair, hours );
                WriteToListView_ThreadSafe( listViewLastTradeVolume, result );

            } else {
                MessageBox.Show( "Please Check the hours Input" );

            }

        }

        private void getBalanceToolStripMenuItem_Click ( object sender, EventArgs e ) {
            List<string[]> balance = c_cexcom.GetBalance();
            new Balance_Form( "c-cex.com", balance ).Show();

        }

        private void exitToolStripMenuItem_Click ( object sender, EventArgs e ) {
            Environment.Exit( Environment.ExitCode );

        }

        private void makeOrderToolStripMenuItem_Click ( object sender, EventArgs e ) {
            C_CEXcom_make_order make_order = new C_CEXcom_make_order( c_cexcom_pairs );
            double amount = 0;
            double rate = 0;
            string selected_pair = string.Empty;
            string result;
            char type;


            while ( true ) {
                if ( make_order.ShowDialog() == DialogResult.OK ) {
                    if ( double.TryParse( make_order.txtAmount.Text, out amount )
                        && double.TryParse( make_order.txtRate.Text, out rate ) ) {
                        selected_pair = ( string ) make_order.comboBoxPair.SelectedValue;
                        selected_pair = selected_pair.Replace( " ", "" );

                        type = ( ( string ) make_order.comboBoxType.SelectedValue ) == "Sell" ? 's' : 'b';
                        result = c_cexcom.MakeOrder( selected_pair, amount, type, rate );
                        dynamic json = DynamicJson.Parse( result );


                        MessageBox.Show( "Your Order ID is: " + json.@return, "Make Order" );
                        break;
                    }
                    MessageBox.Show( "Error", "Please check the numbers you entered" );

                } else {
                    break;
                }
            }


        }

        private void cancelOrderToolStripMenuItem_Click ( object sender, EventArgs e ) {
            C_CEXcom_cancel_order cancel_order = new C_CEXcom_cancel_order();
            int order_id = 0;

            while ( true ) {
                if ( cancel_order.ShowDialog() == DialogResult.OK ) {
                    if ( int.TryParse( cancel_order.txtOrder.Text, out order_id ) ) {

                        string result= c_cexcom.CancelOrder( order_id );
                        MessageBox.Show( result, "Cancel Order" );
                        break;

                        //dynamic json = c_cexcom.CancelOrder( order_id );
                        //string caption = string.Empty;
                        //
                        //if ( json.error() ){  // the same as json.IsDefined("error");
                        //    caption = "Error";
                        //    MessageBox.Show( json.error, caption );
                        //
                        //} else {
                        //    break;
                        //
                        //}


                    }

                } else {
                    break;
                }
            }



        }

        private void btnGet_self_trade_history_Click ( object sender, EventArgs e ) {
           
            selected_pair = selected_pair.Replace(" ", "");
            string self_trade_history = c_cexcom.SelfTradeHistory(date_from, date_to, selected_pair);
            self_trade_history = self_trade_history.Replace("return", "returned");

            dynamic json2 = (dynamic)DynamicJson.Parse(self_trade_history);

            if (json2.returned == "No trade history for this period")
            {
                MessageBox.Show("No History for this period", "Self Trade History");
                return;
            }

            dynamic[] json = (dynamic[])json2.returned;

            List<string[]> list = new List<string[]>();
            for (int i = 0; i < json.Length; i++)
            {
                list.Add(
                    new string[]{
                    HelperClass.Parse_int( json[i].id ),
                    HelperClass.getDateTimeFromJsonString( json[i].dt ),
                    json[i].type,
                    HelperClass.Parse_double( json[i].amount ),
                    HelperClass.Parse_int( json[i].rate ),
                    HelperClass.Parse_double( json[i].backrate )
                }
                );
            }

            WriteToListView_ThreadSafe(listViewSelfTradeHistory, list);
        }

        void bw_update_single_market_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e ) {
            //ChangeEnablePropertyForControl_ThreadSafe( panelCryptsy, true );

            //WriteToListView_ThreadSafe( listViewCryptsyRecentTrades, CRYPTSYcom.getRecentTrades( selected_pair_cryptsy ) );
            //WriteToListView_ThreadSafe( listViewCryptsyBuyOrder, CRYPTSYcom.getBuyOrders( selected_pair_cryptsy ) );
            //WriteToListView_ThreadSafe( listViewCryptsySellOrder, CRYPTSYcom.getSellOrders( selected_pair_cryptsy ) );
        }

        void bw_update_single_market_DoWork ( object sender, DoWorkEventArgs e ) {
            while ( !CRYPTSYcom.download_single_market_data_complete ) ;

        }

        private void pictureBoxloading_Paint ( object sender, PaintEventArgs e ) {
            var g = e.Graphics;
            g.DrawImageUnscaled( ( sender as PictureBox ).Image, ( sender as PictureBox ).Location );
        }

        #region Set API
        private void API_crypstycomToolStripMenuItem_Click ( object sender, EventArgs e ) {
            SetAPI_Key apiKey = new SetAPI_Key(
                "Cryptsy.com API",
                "API Public Key",
                "API Private Key",
                ModifyRegistry.Read( CRYPTSYcom.API_KEY_registry_key ),
                ModifyRegistry.Read( CRYPTSYcom.API_Private_KEY_registry_key )
                );

            if ( apiKey.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                CRYPTSYcom.API_Public_Key = apiKey.txtAPI1.Text;
                CRYPTSYcom.API_Private_Key = apiKey.txtAPI2.Text;
                ModifyRegistry.Write( CRYPTSYcom.API_KEY_registry_key, apiKey.txtAPI1.Text );
                ModifyRegistry.Write( CRYPTSYcom.API_Private_KEY_registry_key, apiKey.txtAPI2.Text );


            }
        }

        private void API_c_cexcomToolStripMenuItem_Click ( object sender, EventArgs e ) {
            SetAPI_Key apiKey = new SetAPI_Key(
                "C-CEX.com APIs",
                "API Key",
                "Mechant Key",
                ModifyRegistry.Read( C_CEXcom.API_KEY_registry_key ),
                ModifyRegistry.Read( C_CEXcom.MERCHANT_KEY_registry_key )
            );

            if ( apiKey.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                c_cexcom.API_KEY = apiKey.txtAPI1.Text;
                c_cexcom.MERCHANT_KEY = apiKey.txtAPI2.Text;
                ModifyRegistry.Write( C_CEXcom.API_KEY_registry_key, apiKey.txtAPI1.Text );
                ModifyRegistry.Write( C_CEXcom.MERCHANT_KEY_registry_key, apiKey.txtAPI2.Text );


            }
        }

        private void API_poloniexcomToolStripMenuItem_Click ( object sender, EventArgs e ) {
            SetAPI_Key apiKey = new SetAPI_Key(
                "Poloniex APIs",
                "API Key",
                "Secret Key",
                ModifyRegistry.Read( POLONIEXcom.API_KEY_registry_key ),
                ModifyRegistry.Read( POLONIEXcom.API_Private_KEY_registry_key )
            );

            if ( apiKey.ShowDialog() == System.Windows.Forms.DialogResult.OK ) {
                POLONIEXcom.API_Public_Key = apiKey.txtAPI1.Text;
                POLONIEXcom.API_Private_Key = apiKey.txtAPI2.Text;
                ModifyRegistry.Write( POLONIEXcom.API_KEY_registry_key, apiKey.txtAPI1.Text );
                ModifyRegistry.Write( POLONIEXcom.API_Private_KEY_registry_key, apiKey.txtAPI2.Text );


            }
        }
        #endregion








        public string[] drives { get; set; }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            ticker_timer.Stop();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            ticker_timer.Stop();
        }
    }
}
